/*
 * by cansik / Florian
 * Datum: 07.05.2010
 * Zeit: 08:04
 * 
 * Update 21.01.2011 (Regex Strings)
 *
 */
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text.RegularExpressions;

namespace PixelReplacer
{
	/// <summary>
	/// Does parse a string into PixelRules
	/// </summary>
	public class RuleParser
	{
        /// <summary>
        /// Create new instance of RuleParser
        /// </summary>
		public RuleParser()
		{
		}
		
        /// <summary>
        /// Parse a string into PixelRules
        /// </summary>
        /// <param name="code">String with the Rules</param>
        /// <returns>An array of PixelRules</returns>
		public PixelRule[] ParseRules(string code)
		{
			List<PixelRule> rules = new List<PixelRule>();
			
			//Comments rausfiltern
			Regex.Replace(code, @"(/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+/)|(//.*)", "", RegexOptions.IgnoreCase);

            MatchCollection rulesegments = Regex.Matches(code, @"(?<name>\w+)\s*\{(?<attributes>[\w;=,()\s]*)\}", RegexOptions.IgnoreCase | RegexOptions.Singleline);
			
			foreach(Match rulematch in rulesegments)
			{
				PixelRule temp = new PixelRule();
				
				temp.Name = rulematch.Groups["name"].Value;
				
				string attributecode = rulematch.Groups["attributes"].Value;
				
				MatchCollection attributesegments = Regex.Matches(attributecode, @"(?<attname>\w)[\s]*\([\s]*(?<lower>[0-9]+(?:\.[0-9]*)?)[\s]*,[\s]*(?<upper>[0-9]+(?:\.[0-9]*)?)[\s]*\)[\s]*;", RegexOptions.IgnoreCase);
				foreach(Match attributmatch in attributesegments)
				{
					switch (attributmatch.Groups["attname"].Value.ToLower()) {
						case "a":
							temp.A = new PixelRange(Convert.ToInt32(attributmatch.Groups["lower"].Value), Convert.ToInt32(attributmatch.Groups["upper"].Value));
							break;
						case "r":
							temp.R = new PixelRange(Convert.ToInt32(attributmatch.Groups["lower"].Value), Convert.ToInt32(attributmatch.Groups["upper"].Value));
							break;
						case "g":
							temp.G = new PixelRange(Convert.ToInt32(attributmatch.Groups["lower"].Value), Convert.ToInt32(attributmatch.Groups["upper"].Value));
							break;
						case "b":
							temp.B = new PixelRange(Convert.ToInt32(attributmatch.Groups["lower"].Value), Convert.ToInt32(attributmatch.Groups["upper"].Value));
							break;
					}
				}
				Match m = Regex.Match(attributecode, @"(?<attname>\w)+[\s]*\([\s]*(?<alpha>[0-9]+(?:\.[0-9]*)?)[\s]*,[\s]*(?<red>[0-9]+(?:\.[0-9]*)?)[\s]*,[\s]*(?<green>[0-9]+(?:\.[0-9]*)?)[\s]*,[\s]*(?<blue>[0-9]+(?:\.[0-9]*)?)[\s]*\)[\s]*;", RegexOptions.IgnoreCase);
				if (m.Success)
				{
					temp.NewColor = Color.FromArgb(Convert.ToInt32(m.Groups["alpha"].Value), Convert.ToInt32(m.Groups["red"].Value), Convert.ToInt32(m.Groups["green"].Value), Convert.ToInt32(m.Groups["blue"].Value));
				}

                MatchCollection optionsegemtns = Regex.Matches(attributecode, @"(?<attname>[\w]*)\s*=\s*(?<attvalue>[true|false|0|1]+\s*);");
                foreach (Match attributmatch in optionsegemtns)
                {
                    switch (attributmatch.Groups["attname"].Value.ToLower())
                    {
                        case "adapt":
                            temp.AdaptColors = Convert.ToBoolean(attributmatch.Groups["attvalue"].Value);
                            break;
                        //Software Specific
                        //case "vector":
                        //    temp. 
                        //    break;
                    }
                }
				
				rules.Add(temp);
			}
			
			return rules.ToArray();
		}
	}
}
